package com.qiuxiucoding.thread;

import com.alibaba.fastjson.JSONObject;
import com.qiuxiucoding.thread.ExecutorThreadPoolManager;
import com.qiuxiucoding.thread.ThreadPoolDetailInfo;
import com.qiuxiucoding.thread.ThreadPoolMonitor;
import com.qiuxiucoding.thread.ThreadPoolUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName ThreadPoolController
 * @desc 线程池监控接口
 * @authors kantlin
 * @Date 2021/12/17 14:53
 **/

@RestController
@RequestMapping(value = "api/threadpool")
public class ThreadPoolController {
    private static final Logger LOGGER = LoggerFactory.getLogger(ThreadPoolController.class);

    @Autowired
    private ExecutorThreadPoolManager threadPool;

    @Autowired
    private ThreadPoolUtil threadPoolUtil;

    @GetMapping(value = "/getThreadPools")
    private List<String> getThreadPools() {
        List<String> threadPools = new ArrayList();
        if (!this.threadPoolUtil.getThreadPoolExecutorHashMap().isEmpty()) {
            Iterator var2 = this.threadPoolUtil.getThreadPoolExecutorHashMap().entrySet().iterator();

            while (var2.hasNext()) {
                Map.Entry<String, ThreadPoolMonitor> entry = (Map.Entry) var2.next();
                threadPools.add(entry.getKey());
            }
        }
        // for (int i = 0; i <Integer.MAX_VALUE ; i++) {
        //
        //     testThread();
        // }
        return threadPools;
    }

    @GetMapping(value = "/getThreadPoolListInfo")
    @Scheduled(cron = "${thread.poll.status.cron}")
    public List<ThreadPoolDetailInfo> getThreadPoolListInfo() {
        List<ThreadPoolDetailInfo> detailInfoList = new ArrayList();
        if (!this.threadPoolUtil.getThreadPoolExecutorHashMap().isEmpty()) {
            Iterator var2 = this.threadPoolUtil.getThreadPoolExecutorHashMap().entrySet().iterator();
            while (var2.hasNext()) {
                Map.Entry<String, ThreadPoolMonitor> entry = (Map.Entry) var2.next();
                ThreadPoolDetailInfo threadPoolDetailInfo = this.threadPoolInfo(entry.getValue(), (String) entry.getKey());
                detailInfoList.add(threadPoolDetailInfo);
            }
        }
        LOGGER.info("Execute details of cuurent thread poll:{}", JSONObject.toJSONString(detailInfoList));
        return detailInfoList;
    }

    private ThreadPoolDetailInfo threadPoolInfo(ThreadPoolMonitor threadPool, String threadPoolName) {
        BigDecimal activeCount = new BigDecimal(threadPool.getActiveCount());
        BigDecimal maximumPoolSize = new BigDecimal(threadPool.getMaximumPoolSize());
        BigDecimal result = activeCount.divide(maximumPoolSize, 2, 4);
        NumberFormat numberFormat = NumberFormat.getPercentInstance();
        numberFormat.setMaximumFractionDigits(2);
        int queueCapacity = 0;
        return new ThreadPoolDetailInfo(threadPoolName, threadPool.getPoolSize(), threadPool.getCorePoolSize(), threadPool.getLargestPoolSize(), threadPool.getMaximumPoolSize(), threadPool.getCompletedTaskCount(), threadPool.getActiveCount(), threadPool.getTaskCount(), threadPool.getKeepAliveTime(TimeUnit.MILLISECONDS), new Double(result.doubleValue() * 100).intValue(), queueCapacity, threadPool.getQueue().size(), threadPool.getTaskCount() == 0L ? 0L : threadPool.getTotalDiff() / threadPool.getTaskCount());
    }

    public void testThread() {
        threadPool.getHighPriorityExecutor().submit(() -> {
            System.out.println("aaaaa");

        });
    }
}
